package com.jayqqaa12.service.system;

import com.github.abel533.echarts.axis.CategoryAxis;
import com.github.abel533.echarts.axis.ValueAxis;
import com.github.abel533.echarts.code.Magic;
import com.github.abel533.echarts.code.Tool;
import com.github.abel533.echarts.code.Trigger;
import com.github.abel533.echarts.feature.MagicType;
import com.github.abel533.echarts.json.GsonOption;
import com.github.abel533.echarts.series.Line;
import com.github.abel533.echarts.style.AreaStyle;
import com.github.abel533.echarts.style.ItemStyle;
import com.github.abel533.echarts.style.itemstyle.Normal;
import com.google.common.collect.Lists;
import com.jayqqaa12.common.Consts;
import com.jayqqaa12.jbase.jfinal.auto.BaseService;
import com.jayqqaa12.jbase.sdk.util.ShiroExt;
import com.jayqqaa12.jbase.util.DateUtil;
import com.jayqqaa12.jbase.util.IpUtil;
import com.jayqqaa12.model.json.Form;
import com.jayqqaa12.model.system.Log;
import com.jayqqaa12.model.system.Res;
import com.jayqqaa12.model.system.User;
import com.jayqqaa12.shiro.SessionDAO;
import com.jfinal.core.Controller;
import eu.bitwalker.useragentutils.Browser;
import eu.bitwalker.useragentutils.UserAgent;

import java.util.List;
import java.util.stream.Collectors;

/**
 * Generated by Jbase.
 */
public class LogService extends BaseService<Log> {

	public static LogService me(){
		
		return me(LogService.class);
	}

    public void insert(Controller con, int operation) {

        UserAgent userAgent = UserAgent.parseUserAgentString(con.getRequest().getHeader("User-Agent"));
        Browser browser = userAgent.getBrowser();

        String ip = IpUtil.getIp(con.getRequest());
        String from = con.getRequest().getHeader("Referer");
        User user = ShiroExt.getSessionAttr(Consts.SESSION_USER);
        Log event = new Log().setIp(ip).setFrom(from);
        if (user != null)
            event.setUid(user.getId());

        event.setUrl(con.getRequest().getRequestURI());
        event.setBrowser(browser.getName());
        event.setOperation(operation).saveAndDate();

    }

    public Log getVisitCount() {

        Log log = new Log();
        log.put("visit", dao.findFirst("SELECT count(*)as c FROM `system_log` where operation =1 ").getLong("c"));
        log.put("login", dao.findFirst("SELECT count(*)as c FROM `system_log` where operation =2 ").getLong("c"));
        log.put("online", SessionDAO.me.getActiveSessions().size());

        return log;
    }


    public List<Log> log(Form from) {

        List<Res> resList = Res.dao.findAllByCache();

        List<Log> list = dao.findAllByWhere(from.getWhereAndLimit());
        for (Log log : list) {
            List<Res> ret = resList.stream().filter(r ->r.getUrl()==log.getUrl() ).collect(Collectors.toList());
            if (!ret.isEmpty()) log.putModel("res", ret.get(0));
        }

        return list;
    }

    public GsonOption chart() {

        List<Log> logs = dao.find(sql("system_log.chart"));

        List<Object> date = Lists.newArrayList();

        for (int i = 6; i >= 0; i--) {
            date.add(DateUtil.addDay(-i));
        }

        GsonOption option = new GsonOption();
        option.legend("访问", "登录", "保存", "删除");
        option.toolbox()
                .show(true)
                .feature(Tool.mark, Tool.dataView, new MagicType(Magic.line, Magic.bar), Tool.restore, Tool.saveAsImage);

        option.calculable(true);
        option.tooltip().trigger(Trigger.axis);

        CategoryAxis valueAxis = new CategoryAxis();
        valueAxis.setData(date);
        option.xAxis(valueAxis);
        option.yAxis(new ValueAxis());

        Line[] lines = new Line[]{new Line(), new Line(), new Line(), new Line()};

        int i = 1;
        for (Line line : lines) {
            int type = i++;
            if (type == Log.EVENT_VISIT) line.name("访问");
            if (type == Log.EVENT_LOGIN) line.name("登录");
            if (type == Log.EVENT_ADD) line.name("保存");
            if (type == Log.EVENT_DELETE) line.name("删除");
            line.itemStyle(new ItemStyle().normal(new Normal().areaStyle(new AreaStyle())));

            List<Object> objs = Lists.newArrayList();

            for (Object d : date) {
                boolean isType = false;
                for (Log log : logs) {
                    if (log.getOperation() == type && log.getStr("date").equals((String) d)) {
                        objs.add(log.getLong("c"));
                        isType = true;
                    }
                }
                if (!isType) objs.add(0);
            }

            line.setData(objs);

//            line.setData(date.stream()
//                    .map(d -> logs.stream()
//                            .map(log -> { return setCount(log, type, d);})
//                            .mapToLong(log -> log.getLong("c")))
//                    .collect(Collectors.toList()));
        }
        option.series(lines);
        return option;
    }

//    private Log setCount(Log log, int type, Object d) {
//        boolean rst= log.getOperation() == type && log.getStr("date").equals((String) d);
//        if(!rst) log.set("c",0L);
//        return log;
//    }


    public Log browser() {
        Log map = new Log();

        map.put("chrome", 0L);
        map.put("ie", 0L);
        map.put("firefox", 0L);
        map.put("opera", 0L);
        map.put("safari", 0L);

        for (Log log : dao.find(sql("system_log.browser"))) {

            String brower = log.getBrowser().toLowerCase();
            if (brower.contains("chrome")) {
                map.put("chrome", map.getLong("chrome") + log.getLong("c"));
            }
            if (brower.toLowerCase().contains("firefox")) {
                map.put("firefox", map.getLong("firefox") + log.getLong("c"));
            }
            if (brower.toLowerCase().contains("opera")) {
                map.put("opera", map.getLong("opera") + log.getLong("c"));
            }
            if (brower.toLowerCase().contains("explorer")) {
                map.put("ie", map.getLong("ie") + log.getLong("c"));
            }
            if (brower.toLowerCase().contains("safari")) {
                map.put("safari", map.getLong("safari") + log.getLong("c"));
            }
        }
        return map;
    }
}
